﻿// ===============================================================================
// XCI.NET 西安交通信息WinForm开发框架 2018 版权所有
// ===============================================================================
using System.IO;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;

namespace XCI.Helper
{
    /// <summary>
    /// Json序列化操作类
    /// </summary>
    public static class JsonHelper
    {
        /// <summary>
        /// 反序列化Json文件
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="path">文件路径</param>
        /// <param name="defaultValue">无数据时的默认值</param>
        public static T DeserializeByPath<T>(string path, T defaultValue = default(T))
        {
            T data = default(T);
            if (File.Exists(path))
            {
                var json = File.ReadAllText(path, System.Text.Encoding.UTF8);
                data = JsonConvert.DeserializeObject<T>(json);
            }
            if (data != null)
            {
                return data;
            }
            return defaultValue;
        }

        /// <summary>
        /// 反序列化Json字符串
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="json">json字符串</param>
        /// <param name="settings">配置</param>
        public static T Deserialize<T>(string json, JsonSerializerSettings settings = null)
        {
            if (settings == null)
            {
                settings = GetDefaultSetting(Formatting.None);
            }
            return string.IsNullOrEmpty(json) ? default(T) : JsonConvert.DeserializeObject<T>(json, settings);
        }

        /// <summary>
        /// 把数据对象Json序列化到文件
        /// </summary>
        /// <param name="path">文件路径</param>
        /// <param name="data">数据对象</param>
        /// <param name="formatting">格式化方式</param>
        public static void SerializeByPath(string path, object data, Formatting formatting = Formatting.None)
        {
            IOHelper.CreateDirectoryByPath(path);
            var json = JsonConvert.SerializeObject(data, GetDefaultSetting(formatting));
            File.WriteAllText(path, json, System.Text.Encoding.UTF8);
        }

        /// <summary>
        /// 把数据对象Json序列化到文件
        /// </summary>
        /// <param name="path">文件路径</param>
        /// <param name="data">数据对象</param>
        /// <param name="settings">格式</param>
        public static void SerializeByPath(string path, object data, JsonSerializerSettings settings)
        {
            IOHelper.CreateDirectoryByPath(path);
            var json = JsonConvert.SerializeObject(data, settings);
            File.WriteAllText(path, json, System.Text.Encoding.UTF8);
        }

        /// <summary>
        /// 把数据对象Json序列化为字符串
        /// </summary>
        /// <param name="data">数据对象</param>
        /// <param name="formatting">格式化方式</param>
        public static string Serialize(object data, Formatting formatting = Formatting.None)
        {
            if (data == null) return string.Empty;
            return JsonConvert.SerializeObject(data, GetDefaultSetting(formatting));
        }

        /// <summary>
        /// 把数据对象Json序列化为字符串
        /// </summary>
        /// <param name="data">数据对象</param>
        /// <param name="settings">格式</param>
        public static string Serialize(object data, JsonSerializerSettings settings)
        {
            if (data == null) return string.Empty;
            return JsonConvert.SerializeObject(data, settings);
        }

        /// <summary>
        /// 获取默认Json序列化默认设置
        /// </summary>
        /// <param name="formatting">Json是否格式化</param>
        public static JsonSerializerSettings GetDefaultSetting(Formatting formatting = Formatting.None)
        {
            var settings = new JsonSerializerSettings
            {
                ReferenceLoopHandling = ReferenceLoopHandling.Error,
                NullValueHandling = NullValueHandling.Ignore,
                DateFormatString = "yyyy-MM-dd HH:mm:ss",
                Formatting = formatting
            };
            settings.Converters.Add(new StringEnumConverter { NamingStrategy = new CamelCaseNamingStrategy() });
            return settings;
        }

        /// <summary>
        /// Json对象转换
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="obj">待转换的对象</param>
        /// <returns>返回转换后的对象</returns>
        public static T ToObject<T>(object obj)
        {
            switch (obj)
            {
                case T value1:
                    return value1;
                case JContainer value2:
                    return value2.ToObject<T>();
                default:
                    return default(T);
            }
        }
    }
}